/**
 * Copyright (c) Huawei Technologies Co., Ltd. 1987-2021. All rights reserved.
*/

package com.gitee.fufu669.config.exception;

import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.CollectionUtils;
import org.springframework.validation.BindException;
import org.springframework.validation.FieldError;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.view.json.MappingJackson2JsonView;

import com.fasterxml.jackson.core.JsonGenerator;

// 注解
@SuppressWarnings({ "rawtypes" })
/** @author wangfupeng */
/**
 * TODO
*/
public class CacheServerExceptionHandler {

    // 日志对象
    private static final Logger logger = LoggerFactory.getLogger(CacheServerExceptionHandler.class);

    // 将java对象转为json的注解
    @ResponseBody
    // 注解
    @ExceptionHandler(CacheServerException.class)
    /**
     * TODO
    */
    public ModelAndView serverExceptionHandler(RuntimeException e, HttpServletResponse response) {

        // 创建
        ModelAndView mav = new ModelAndView();
        // 判断
        if (e instanceof CacheServerException) {
            // 字符串赋值
            String status = ((CacheServerException) e).getCode();
            // 创建
            Jackson2JsonView view = new Jackson2JsonView();
            // 创建
            Map<String, Object> attributes = new HashMap<>(16);
            // 塞入
            attributes.put("code", status);
            // 塞入
            attributes.put("msg", e.getMessage());
            // 创建
            attributes.put("data", new CacheEmptyInstance());
            // 塞入
            attributes.put("more info", "");
            // TODO
            view.setAttributesMap(attributes);
            // TODO
            view.setPrettyPrint(true);
            // TODO
            mav.setView(view);
            logger.info("【Error】", e);
        }
        // 返回
        return mav;
    }

    // 将java对象转为json的注解
    @ResponseBody
    // 注解
    @ExceptionHandler(BindException.class)
    /**
     * TODO
    */
    public ModelAndView bindExceptionHandler(BindException e, HttpServletResponse response) {
        // 创建
        ModelAndView mav = new ModelAndView();
        // 创建
        Jackson2JsonView view = new Jackson2JsonView();
        // 创建
        Map<String, Object> attributes = new HashMap<>(16);
        // 塞入
        attributes.put("code", CacheServerErrorCode.EXCEPTIONHANDLER_PARAM_ERROR);
        // 塞入
        attributes.put("msg", "参数有误");
        // 创建
        attributes.put("data", new CacheEmptyInstance());
        // TODO
        List<ObjectError> errors = e.getBindingResult().getAllErrors();
        // 创建
        StringBuilder moreInfo = new StringBuilder();
        // 判断
        if (!CollectionUtils.isEmpty(errors)) {
            // 遍历
            errors.stream().filter(error -> error instanceof FieldError).forEach(error -> moreInfo
                    // 增加字符串
                    .append(((FieldError) error).getField()).append(":").append(error.getDefaultMessage()).append(";"));
        }
        // 转换成字符串
        attributes.put("more info", moreInfo.toString());
        // TODO
        view.setAttributesMap(attributes);
        // TODO
        view.setPrettyPrint(true);
        // TODO
        mav.setView(view);
        logger.info("【Error】", e);
        // 返回
        return mav;
    }

    // 将java对象转为json的注解
    @ResponseBody
    // 注解
    @ExceptionHandler(Exception.class)
    /**
     * TODO
    */
    public ModelAndView exceptionHandler(Exception e, HttpServletResponse response) {
        // 创建
        ModelAndView mav = new ModelAndView();
        // 创建
        Jackson2JsonView view = new Jackson2JsonView();
        // 创建
        Map<String, Object> attributes = new HashMap<>(16);
        // 判断
        if (e instanceof Exception) {
            // 塞入
            attributes.put("code", CacheServerErrorCode.UNKNOWN);
            /** attributes.put("msg", "未知错误");*/
            /** .substring(0, 190) */
            attributes.put("msg", temp(e));
            /** attributes.put("msg", e.toString());*/
            attributes.put("data", new CacheEmptyInstance());
            // 塞入
            attributes.put("more info", "");
            // TODO
            view.setAttributesMap(attributes);
            // TODO
            view.setPrettyPrint(true);
            // TODO
            mav.setView(view);
            logger.info("【Error】", e);
        }
        // 返回
        return mav;
    }

    // TODO
    private String temp(Exception e) {
        // 字符串赋值
        String aaa = e.getMessage();
        // 遍历
        for (StackTraceElement element : e.getStackTrace()) {
            // 增加
            aaa += element.toString();
        }

        // 返回
        return aaa;
    }

    // TODO
    class Jackson2JsonView extends MappingJackson2JsonView {
        // 覆盖父类方法的注解
        @Override
        /**
         * TODO
        */
        protected void writePrefix(JsonGenerator generator, Object object) throws IOException {
        }

        // 覆盖父类方法的注解
        @Override
        /**
         * TODO
        */
        protected void writeSuffix(JsonGenerator generator, Object object) throws IOException {
        }
    }

}
